package com.baidu.ueditor.upload;

import com.baidu.ueditor.PathFormat;
import com.baidu.ueditor.define.AppInfo;
import com.baidu.ueditor.define.BaseState;
import com.baidu.ueditor.define.FileType;
import com.baidu.ueditor.define.State;
import com.sniper.data.DataValues;
import com.sniper.model.Files;
import com.sniper.web.utils.FilesUtil;
import com.sniper.web.utils.SystemConfigUtil;
import com.sniper.web.utils.UserDetailsUtils;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

public class BinarySpringMvcUploader {


    public static State save(HttpServletRequest request, Map<String, Object> conf) {

        // 检测是否是form表单提交
        if (!ServletFileUpload.isMultipartContent(request)) {
            return new BaseState(false, AppInfo.NOT_MULTIPART_CONTENT);
        }

        // 下面附件数据的获取和spring mvc配置的数据获取you冲突，如果想一起用的话，这里必须按照spring mvc的格式去写
        try {
            MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
            // 获取上传文件
            MultipartFile multipartFile = multipartHttpServletRequest.getFile(conf.get("fieldName").toString());

            if (multipartFile.getSize() == 0) {
                return new BaseState(false, AppInfo.NOTFOUND_UPLOAD_DATA);
            }

            int minImgWidth = 1000;
            if (SystemConfigUtil.getInt("minImgWidth") > 0) {
                minImgWidth = SystemConfigUtil.getInt("minImgWidth");
            }
            // 检测图片最小的是否规范
            UserDetailsUtils detailsUtils = new UserDetailsUtils();
            if (!detailsUtils.validRole(DataValues.ROLE_ADMIN)) {
                long minFileSizeL = SystemConfigUtil.getLong("minUploadFileSize");
                if (minFileSizeL > 0 && multipartFile.getSize() < minFileSizeL) {
                    return new BaseState(false, AppInfo.FILE_TO_SMALL);
                }
            } else {
                //管理员无限制
                minImgWidth = 0;
            }

            String savePath = (String) conf.get("savePath");
            String originFileName = multipartFile.getOriginalFilename();
            // 文件后缀一律小写
            String suffix = FileType.getSuffixByFilename(originFileName).toLowerCase();

            originFileName = originFileName.substring(0, originFileName.length() - suffix.length());
            savePath = savePath + suffix;

            long maxSize = (Long) conf.get("maxSize");

            if (!validType(suffix, (String[]) conf.get("allowFiles"))) {
                return new BaseState(false, AppInfo.NOT_ALLOW_FILE_TYPE);
            }

            savePath = PathFormat.parse(savePath, originFileName);

            String rootPath = (String) conf.get("rootPath");
            String physicalPath = rootPath + savePath;
            physicalPath = physicalPath.replace("//", "/");
            InputStream is = multipartFile.getInputStream();
            // 数据的保存
            State storageState = StorageManager.saveFileByInputStream(is, physicalPath, maxSize);
            is.close();


            // 附件数据组装
            Files attachments = new Files();
            // 可能是原图，也可能是缩略图
            attachments.setNewPath(savePath);
            // 发送到图片服务器
            String rootDir = FilesUtil.getRootDir();

            // 原图
            attachments.setOldName(savePath);
            attachments.setSize(multipartFile.getSize());
            // 获取后缀
            attachments.setFileType(multipartFile.getContentType());
            attachments.setUid(detailsUtils.getAdminUser().getId());
            try {
                attachments.setHash(DigestUtils.md5Hex(multipartFile.getBytes()));
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 插入数据

            // 检测图片的大小
            if (storageState.isSuccess()) {
                storageState.putInfo("url", PathFormat.format(savePath));
                storageState.putInfo("type", suffix);
                storageState.putInfo("original", originFileName + suffix);
            }
            return storageState;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new BaseState(false, AppInfo.IO_ERROR);
    }

    private static boolean validType(String type, String[] allowTypes) {
        List<String> list = Arrays.asList(allowTypes);
        return list.contains(type);
    }
}
